package common.fetch;

import com.han.http.util.Regex;
import common.entity.ArticleUrlEntity;
import common.entity.DetailListEntity;
import common.entity.LeaderNewsEntity;
import common.sql.Operator;
import common.util.ContentUtil;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.text.SimpleDateFormat;
import java.util.*;

import static com.han.http.util.Print.printlnErr;
import static com.han.http.util.Print.printlnInfo;

/**
 * @author: Han
 * @date: 2018/9/26 9:36
 * @dscription: 四川省质量技术监督局
 */
public class Aqts extends Thread {

    /**
     * 记录第一个链接的日期
     */
    private Date newLastDate;
    private DetailListEntity detailListEntity;
    private Date lastDate;
    private Operator operator;

    Aqts(DetailListEntity detailListEntity) {
        this.detailListEntity = detailListEntity;
        operator = Operator.getInstance();
    }

    @Override
    public void run() {
        String rowUrl = detailListEntity.getUrl();
        int pageNo = 0;
        lastDate = detailListEntity.getLastDate();
        int emptyCount = 0;
        Random random = new Random();
        while (emptyCount <= 2) {
            String url;
            if (pageNo == 0) {
                url = rowUrl.replace("_%d", "");
            } else {
                url = String.format(rowUrl, pageNo);
            }
            printlnInfo(this.getName() + " 第" + pageNo + "页开始抓取");
            List<ArticleUrlEntity> articleList = new ArrayList<>();
            try {
                articleList = getArticleList(url);
            } catch (NullPointerException e) {
                printlnErr(this.getName() + " 没有获取到链接list:" + url);
            } finally {
                try {
                    int interval = random.nextInt(1000) + 200;
                    Thread.sleep(interval);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果连续三次文章列表为空,跳出
            if (articleList.isEmpty()) {
                printlnInfo(this.getName() + " 第" + pageNo + "没有合适链接");
                emptyCount++;
            } else {
                printlnInfo(this.getName() + " 第" + pageNo + "链接数:" + articleList.size());
                detailListEntity.setUsedCount(pageNo);
                emptyCount = 0;
            }
            for (ArticleUrlEntity articleUrl : articleList) {
                try {
                    getArticleDetail(articleUrl);
                } catch (Exception e) {
                    printlnErr(this.getName() + " " + articleUrl + "检索失败");
                    e.printStackTrace();
                } finally {
                    try {
                        int interval = random.nextInt(1000) + 200;
                        Thread.sleep(interval);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            pageNo++;
        }
        //更新新闻列表链接信息
        detailListEntity.setLastDate(newLastDate);
        operator.updateDetailList(detailListEntity);
    }

    /**
     * 获取文章链接list
     *
     * @param url 列表页url
     * @return 文章链接URL
     */
    private List<ArticleUrlEntity> getArticleList(String url) {
        List<ArticleUrlEntity> articleList = new ArrayList<>();
        List<String> repeatCheckList = new ArrayList<>();
        try {
            Connection connection = Jsoup.connect(url);
            connection.timeout(1000 * 30);
            Document document = connection.get();
            Element element = document.getElementById("p_list_r_cont");
            Elements liEles = element.getElementsByTag("li");
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            for (Element tempEle : liEles) {
                Element aEle = tempEle.select("a").first();
                if (Objects.isNull(aEle)) {
                    continue;
                }
                String href = aEle.attr("href");
                if (href.contains("javascript")) {
                    continue;
                }
                String dateStr = Regex.matchString(tempEle.text(), "[\\d]{2,4}-[\\d]{1,2}-[\\d]{1,2}");
                Date date = simpleDateFormat.parse(dateStr);
                if (date.before(lastDate)) {
                    continue;
                }
                //将第一个文章链接的日期赋予新最后更新日期
                if (Objects.isNull(newLastDate)) {
                    newLastDate = date;
                }
                //清洗链接
                href = ContentUtil.washArticleUrl(href, url);
                //放入检测容器,如果存在,就下一个,否则放入检测容器
                if (repeatCheckList.contains(href)) {
                    continue;
                } else {
                    repeatCheckList.add(href);
                }
                ArticleUrlEntity articleUrlEntity = new ArticleUrlEntity(href, dateStr);
                articleList.add(articleUrlEntity);
            }
        } catch (NullPointerException e) {
            throw e;
        } catch (Exception e) {
            printlnErr(e.getMessage() + ":" + url);
            e.printStackTrace();
        }
        return articleList;
    }

    /**
     * 获取文章内容并上传数据库
     *
     * @param articleUrlEntity 文章链接实体
     * @throws Exception 抛出异常
     */
    private void getArticleDetail(ArticleUrlEntity articleUrlEntity) throws Exception {
        String url = articleUrlEntity.getUrl();
        Connection connection = Jsoup.connect(url);
        connection.timeout(1000 * 30);
        Document document = connection.get();
        Element detail = document.getElementById("contMain");
        //标题
        Elements titleEle = detail.getElementsByTag("h2");
        String title = titleEle.text();
        //日期
        String time = articleUrlEntity.getTime();
        //文本内容
        Element textEle = detail.getElementById("cmsArticleContent");
        String text = textEle.text();
        String sum = text.replaceAll("(?<=。)\\s[\\s\\S]*", "");

        LeaderNewsEntity entity = new LeaderNewsEntity(null, url, title, detailListEntity.getSource(), time, sum);
        ContentUtil.storeNews(entity, text, this.getName());
    }

}
